package serverGUI;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;

import javax.imageio.ImageIO;
import javax.swing.*;

import server.ServiceManager;

@SuppressWarnings("serial")
/**
 * The class containing all the required methods and calls from and to the GUI
 */
public class GUI extends JFrame {
	
	// Graphics constants
	private static GraphicsEnvironment gui_graphicsEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
	private static GraphicsDevice gui_graphicsDev = gui_graphicsEnv.getDefaultScreenDevice();
	private static GraphicsConfiguration gui_graphicsConf = gui_graphicsDev.getDefaultConfiguration();
	
    // constants used in the GUI
	public GUI gui = this;
	public JTextArea consoleTextArea = new JTextArea();
	private ServiceManager serviceManager;	
	public RadarThread radarThread;
	public boolean serverRunning = false;	
	int gui_width = 500;
	int gui_height = 350;
	
	// constants for the radar
	public int[] radar_xpoints = new int[121];
	public int[] radar_ypoints = new int[121];
	public static int radar_npoints = 121;
	public Polygon radar_polygon = new Polygon(radar_xpoints,radar_ypoints,radar_npoints);
	
	//Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
	/**
	 * Constructor for the class GUI.
	 */
	public GUI() {
		super("iPhone to NXT :: Server Application", gui_graphicsConf);
	    javax.swing.SwingUtilities.invokeLater(new Runnable() {
	        public void run() {
	            try {
					createAndShowGUI();
				} catch (IOException e) {
					e.printStackTrace();
				}
	        }
	    });
	}
	
	/**
	 * Creates and Shows the GUI
	 * @throws IOException 
	 */
	public void createAndShowGUI() throws IOException {
		System.out.println("Starting GUI...");
		
		// set general frame properties
	    gui.setResizable(true);
	    gui.setPreferredSize(new Dimension(gui_width, gui_height));
	    
	    // Get Icon
	    BufferedImage img = null;
	    try {
	        img = ImageIO.read(new File("img/nxt_icon.jpg"));
	        gui.setIconImage(img);
	    	} catch (IOException e) {
	    }
	    
	    // catch the closing event
	    gui.addWindowListener(new WindowAdapter() {
	    	public void windowClosing(WindowEvent e) {
		    	closeGUI();
		    }
		});
	    
	    // Add components
	    Container contentPane = gui.getContentPane();
	    gui.setJMenuBar(createGuiMenuBar());
	    contentPane.add(createRadarPane(), BorderLayout.CENTER);
	    contentPane.add(createButtonPane(), BorderLayout.PAGE_END);
        //contentPane.add(createConsolePane(), BorderLayout.PAGE_END);
                
		// show the frame
		gui.pack();
	    gui.setLocationRelativeTo(null);
		gui.setVisible(true);	
	}

	private Component createRadarPane() {

		JPanel radarPane = new JPanel();
		
		radarPane.setBorder(
			BorderFactory.createCompoundBorder(
				BorderFactory.createCompoundBorder(
					BorderFactory.createTitledBorder("Radar"),
					BorderFactory.createEmptyBorder(2,2,2,2)),
				radarPane.getBorder()));
		
		new RadarThread(gui,radarPane).start();
		
		return radarPane;
	}

	private JPanel createConsolePane() throws IOException {
		
		PipedInputStream piOut;
		PipedInputStream piErr;
		PipedOutputStream poOut;
		PipedOutputStream poErr; 
		
		// Set up System.out 
		piOut = new PipedInputStream(); 
		poOut = new PipedOutputStream(piOut); 
		System.setOut(new PrintStream(poOut, true)); 
		
		// Set up System.err 
		piErr = new PipedInputStream(); 
		poErr = new PipedOutputStream(piErr); 
		System.setErr(new PrintStream(poErr, true));

		//Create a text area.
		consoleTextArea.setEditable(false);
		consoleTextArea.setRows(20);
		consoleTextArea.setColumns(50); 
        JScrollPane areaScrollPane = new JScrollPane(consoleTextArea);
        areaScrollPane.setVerticalScrollBarPolicy(
                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        areaScrollPane.setHorizontalScrollBarPolicy(
        				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        areaScrollPane.setPreferredSize(new Dimension(250, 250));
        areaScrollPane.setBorder(
            BorderFactory.createCompoundBorder(
                BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder("Console"),
                                BorderFactory.createEmptyBorder(2,2,2,2)),
                areaScrollPane.getBorder()));

        //Put everything together.
        JPanel consolePane = new JPanel(new BorderLayout());
        consolePane.add(areaScrollPane, BorderLayout.CENTER);
        consolePane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
        
        // Create reader threads
        new ReaderThread(piOut,consoleTextArea).start();
        //new ReaderThread(piErr,consoleTextArea).start(); 
        
		return consolePane;
	}
	
	/**
	 * Creates and returns the Menu Bar
	 * @return menuBar - JMenuBar
	 */
	private JMenuBar createGuiMenuBar() {
        
		// Creates a menubar for a JFrame
        JMenuBar menuBar = new JMenuBar();
        menuBar.setPreferredSize(new Dimension(90, 20));
        
        // Define and add two drop down menu to the menubar
        JMenu mainMenu = new JMenu("Menu");
        JMenu aboutMenu = new JMenu("About");
        menuBar.add(mainMenu);
        menuBar.add(aboutMenu);
        
        // Create and add simple menu item to one of the drop down menu
        JMenuItem startAction = new JMenuItem("Start Server");
        JMenuItem stopAction = new JMenuItem("Stop Server");
        JMenuItem exitAction = new JMenuItem("Exit");
        JMenuItem helpAction = new JMenuItem("Help");
        JMenuItem aboutAction = new JMenuItem("About");
        
        // add menu entries to main menu
        mainMenu.add(startAction);
        mainMenu.add(stopAction);
         mainMenu.addSeparator();
        mainMenu.add(exitAction);
        
        // add entries to about menu
        aboutMenu.add(helpAction);
         aboutMenu.addSeparator();
        aboutMenu.add(aboutAction);

        // Add a listener to the New menu items
        // Starting the server
        startAction.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            	if (!serverRunning) {
            		System.out.println("GUI :: Starting Server...");
            		serviceManager = new ServiceManager();
            		serverRunning = true;
            	} else {
            		System.out.println("GUI :: Server already started!");
            	}
            }
        });
        // Stopping the server
        stopAction.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            	if (serverRunning) {
	                System.out.println("GUI :: Stopping Server...");
	        	    try {
						serviceManager.shutdown();
					} catch (IOException e) {
						e.printStackTrace();
					}
					serverRunning = false;
            	} else {
            		System.out.println("GUI :: Server not started!");
            	}
            }
        });
        // close the GUI
        exitAction.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent arg0) {
            	closeGUI();
            }
        });
        // ask for help
        helpAction.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent arg0) {
        		String message =
        			"Menu -> Start Server:\n" + 
        			"   Starts Server Connections.\n\n" + 
        			"Menu -> Stop Server:\n" + 
        			"   Stops Server Connections.\n\n" + 
        			"Menu -> Exit:\n" + 
        			"   Closes the Application.\n\n" + 
        			"About -> Help:\n" + 
        			"   Opens this Window.\n\n" + 
        			"About -> About:\n" + 
        			"   Opens the About Window.\n\n"
        			;
        		JOptionPane.showMessageDialog(null, message);
            }
        });
        // open an about window
        aboutAction.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent arg0) {
        		String message =
        			"Developped by:\n" + 
        			"   Balaz\n" + 
        			"   Tim\n" + 
        			"   Jan"
        			;
        		JOptionPane.showMessageDialog(null, message);
            }
        });
        
        return menuBar;
    }

	/**
	 * Create the button to start the server
	 * @return JComponent
	 */
    protected JComponent createButtonPane() {
        JButton button = new JButton("Start Server");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            	if (!serverRunning) {
            		System.out.println("GUI :: Starting Server...");
            		serviceManager = new ServiceManager();
            		serverRunning = true;
            	} else {
            		System.out.println("GUI :: Server already started!");
            	}
            }
        });

        //Center the button in a panel with some space around it.
        JPanel pane = new JPanel(); //use default FlowLayout
        pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
        pane.add(button);

        return pane;
    }


    /**
     * close the GUI
     */
	private void closeGUI() {
		System.out.println("GUI :: Closing Program...");
		if (serverRunning) {
			System.out.println("GUI :: Stopping Server...");
		    try {
				serviceManager.shutdown();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			serverRunning = false;
		}
		setVisible(false);
		System.exit(0);
	}

}
